package com.novax.ex.activity.provider.controller.inner;

import com.alibaba.fastjson.JSON;
import com.novax.ex.activity.open.api.inner.DrawUserTotalApi;
import com.novax.ex.activity.provider.api.ActivityQueryApi;
import com.novax.ex.activity.provider.api.BrokerInvitationRelationshipApi;
import com.novax.ex.activity.provider.api.ResourceApi;
import com.novax.ex.activity.provider.api.SpotApi;
import com.novax.ex.activity.provider.api.model.DrawEntity;
import com.novax.ex.activity.provider.api.model.DrawUpUserDetailRequest;
import com.novax.ex.activity.provider.api.model.DrawUserDetailEntity;
import com.novax.ex.activity.provider.api.model.DrawUserTotalEntity;
import com.novax.ex.activity.provider.api.model.DrawUserTotalResponse;
import com.novax.ex.activity.provider.api.model.InvitationResponse;
import com.novax.ex.activity.provider.api.model.NewPriceEntity;
import com.novax.ex.activity.provider.controller.BaseActivityController;
import com.novax.ex.common.constant.ActivitySpoKeyConstants;
import com.novax.ex.common.constant.InternationalConfig;
import com.novax.ex.common.core.redis.RedisUtil;
import com.novax.ex.common.results.ReturnResult;
import com.novax.ex.common.util.DateUtil;
import org.springframework.web.bind.annotation.RestController;

import jakarta.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Description:
 *
 * @author my.miao
 * @date 2022/7/22 10:14
 */
@RestController
public class DrawUserTotalController extends BaseActivityController implements DrawUserTotalApi {

    @Resource
    private ResourceApi resourceApi;
    @Resource
    private ActivityQueryApi activityQueryApi;
    @Resource
    private SpotApi spotConfigApi;
    @Resource
    private BrokerInvitationRelationshipApi brokerUserInvitationApi;

    @Override
    public void count() {
        Long currentTime = System.currentTimeMillis();// 当前时间戳
        Long fiveDate = currentTime - currentTime % 300000;// 五分钟时间戳
        Date date = new Date(fiveDate);// 获取当前时间
        Date newDate = DateUtil.addSecond(date, -300);// 先获取上一个五分钟的时间
        // 先查活动是否在时间段内、是否开启、是否上架
        ReturnResult<DrawEntity> openedDrawConfig = resourceApi.findOpened();
        if (Objects.nonNull(openedDrawConfig) && openedDrawConfig.isSuccess() && Objects.nonNull(openedDrawConfig.getData())) {
            DrawEntity drawEntity = openedDrawConfig.getData();
            if (drawEntity != null && drawEntity.getStatus() == 1 && drawEntity.getStartTime()
                                                                         .getTime() <= newDate.getTime()
                && newDate.getTime() <= drawEntity.getEndTime()
                .getTime()) {// 活动开启且在活动期限内
                // 查询当前五分钟交易总量，存储到表中
                Map<Long, DrawUserTotalEntity> map = new HashMap<>();
                Map<String, BigDecimal> mapPrice = new HashMap<>();
                // 获取交易区币种
                ReturnResult<List<String>> result = spotConfigApi.symbolModule(InternationalConfig.CHINESE);
                List<String> list = result.getData();
                if (drawEntity.getWalletNumber() > 0 && drawEntity.getWalletLimit()
                                                            .compareTo(BigDecimal.ZERO) > 0) {
                    // 查询充值量
                    ReturnResult<List<DrawUserTotalResponse>> wallerResult = activityQueryApi.drawTotal(1,
                                                                                                        DateUtil.dateTo14String(drawEntity.getStartTime()),
                                                                                                        DateUtil.dateTo14String(drawEntity.getEndTime()),
                                                                                                        DateUtil.dateTo14String(newDate),
                                                                                                        DateUtil.dateTo14String(date));
                    if (wallerResult.getCode() == 200) {
                        List<DrawUserTotalResponse> walletList = wallerResult.getData();
                        for (DrawUserTotalResponse item : walletList) {
                            BigDecimal newPrice = this.newPirce(mapPrice, list, item.getCurrency());
                            BigDecimal walletLimit = item.getAmount()
                                .multiply(newPrice)
                                .setScale(4, BigDecimal.ROUND_DOWN);
                            DrawUserTotalEntity entity = map.get(item.getUserId());
                            if (entity == null) {
                                entity = new DrawUserTotalEntity();
                                entity.setDrawId(drawEntity.getId());
                                entity.setUserId(item.getUserId());
                                entity.setWalletLimit(walletLimit);
                                map.put(item.getUserId(), entity);
                            } else {
                                entity.setWalletLimit(entity.getWalletLimit()
                                                          .add(walletLimit));
                            }
                        }
                    }
                }
                if (drawEntity.getSpotNumber() > 0 && drawEntity.getSpotLimit()
                                                          .compareTo(BigDecimal.ZERO) > 0) {
                    // 查询现货交量
                    ReturnResult<List<DrawUserTotalResponse>> spotResult = activityQueryApi.drawTotal(2,
                                                                                                      DateUtil.dateTo14String(drawEntity.getStartTime()),
                                                                                                      DateUtil.dateTo14String(drawEntity.getEndTime()),
                                                                                                      DateUtil.dateTo14String(newDate),
                                                                                                      DateUtil.dateTo14String(date));
                    if (spotResult.getCode() == 200) {
                        List<DrawUserTotalResponse> spotList = spotResult.getData();
                        for (DrawUserTotalResponse item : spotList) {
                            BigDecimal newPrice = this.newPirce(mapPrice, list, item.getCurrency());
                            BigDecimal spotLimit = item.getAmount()
                                .multiply(newPrice)
                                .setScale(4, BigDecimal.ROUND_DOWN);
                            DrawUserTotalEntity entity = map.get(item.getUserId());
                            if (entity == null) {
                                entity = new DrawUserTotalEntity();
                                entity.setDrawId(drawEntity.getId());
                                entity.setUserId(item.getUserId());
                                entity.setSpotLimit(spotLimit);
                                map.put(item.getUserId(), entity);
                            } else {
                                entity.setSpotLimit(entity.getSpotLimit()
                                                        .add(spotLimit));
                            }
                        }
                    }
                }
                if (drawEntity.getSwapNumber() > 0 && drawEntity.getSwapLimit()
                                                          .compareTo(BigDecimal.ZERO) > 0) {
                    // 查询合约交易量
                    ReturnResult<List<DrawUserTotalResponse>> swapResult = activityQueryApi.drawTotal(3,
                                                                                                      DateUtil.dateTo14String(
                                                                                                          drawEntity.getStartTime()),
                                                                                                      DateUtil.dateTo14String(
                                                                                                          drawEntity.getEndTime()),
                                                                                                      DateUtil.dateTo14String(
                                                                                                          newDate),
                                                                                                      DateUtil.dateTo14String(
                                                                                                          date));
                    if (swapResult.getCode() == 200) {
                        List<DrawUserTotalResponse> swapList = swapResult.getData();
                        for (DrawUserTotalResponse item : swapList) {
                            BigDecimal newPrice = this.newPirce(mapPrice, list, item.getCurrency());
                            BigDecimal swapLimit = item.getAmount()
                                .multiply(newPrice)
                                .setScale(4, BigDecimal.ROUND_DOWN);
                            DrawUserTotalEntity entity = map.get(item.getUserId());
                            if (entity == null) {
                                entity = new DrawUserTotalEntity();
                                entity.setDrawId(drawEntity.getId());
                                entity.setUserId(item.getUserId());
                                entity.setSwapLimit(swapLimit);
                                map.put(item.getUserId(), entity);
                            } else {
                                entity.setSwapLimit(entity.getSwapLimit()
                                                        .add(swapLimit));
                            }
                        }
                    }
                }
                List<Long> userList = new ArrayList<>(map.keySet());// 有交易的用户
                if (userList.size() <= 0) {
                    return;
                }
                // 获取上级邀请人
                ReturnResult<List<InvitationResponse>> returnResult = brokerUserInvitationApi.getInvitedList(userList);
                Map<Long, Long> invitationMap = new HashMap<>();
                if (returnResult.getCode() == 200) {
                    List<InvitationResponse> inviteeList = returnResult.getData();
                    for (InvitationResponse item : inviteeList) {
                        invitationMap.put(item.getInviteeId(), item.getUserId());
                    }
                }
                // 获取上级用户抽奖次数信息表数据
                List<DrawUserDetailEntity> invitationUserDetailList = resourceApi.selectByUserIdList(drawEntity.getId(), new ArrayList<>(invitationMap.values())).getData();

                // 上级用户盲盒记录map
                Map<Long, Long> invitationUserMap = new HashMap<>();
                for (DrawUserDetailEntity item : invitationUserDetailList) {
                    invitationUserMap.put(item.getUserId(), item.getUserId());
                }
                // 获取用户交易总计明细
                List<DrawUserTotalEntity> totalList = resourceApi.selectTotalByUserId(drawEntity.getId(), userList).getData();
                Map<Long, DrawUserTotalEntity> totalMap = totalList.stream()
                    .collect(
                        Collectors.toMap(DrawUserTotalEntity::getUserId, a -> a, (k1, k2) -> k1));
                // 获取用户抽奖次数信息表数据
                List<DrawUserDetailEntity> userDetailList = resourceApi.selectByUserIdList(drawEntity.getId(), userList).getData();
                Map<Long, DrawUserDetailEntity> userDetailMap = userDetailList.stream()
                    .collect(
                        Collectors.toMap(DrawUserDetailEntity::getUserId, a -> a, (k1, k2) -> k1));
                Map<Long, DrawUserDetailEntity> saveUserDetailMap = new HashMap<>();
                Map<Long, DrawUserDetailEntity> upUserDetailMap = new HashMap<>();

                Map<Long, DrawUserTotalEntity> saveUserTotalMap = new HashMap<>();
                Map<Long, DrawUserTotalEntity> upUserTotalMap = new HashMap<>();
                for (DrawUserTotalEntity item : map.values()) {
                    BigDecimal wallet = BigDecimal.ZERO;
                    BigDecimal spot = BigDecimal.ZERO;
                    BigDecimal swap = BigDecimal.ZERO;
                    DrawUserTotalEntity totalEntity = totalMap.get(item.getUserId());// 用户总的充值，交易量
                    if (totalEntity == null) {// 之前没有交易过
                        saveUserTotalMap.put(item.getUserId(), item);
                        wallet = item.getWalletLimit();
                        spot = item.getSpotLimit();
                        swap = item.getSwapLimit();
                    } else {
                        upUserTotalMap.put(item.getUserId(), item);
                        wallet = totalEntity.getWalletLimit()
                            .add(item.getWalletLimit());
                        spot = totalEntity.getSpotLimit()
                            .add(item.getSpotLimit());
                        swap = totalEntity.getSwapLimit()
                            .add(item.getSwapLimit());
                    }
                    DrawUserDetailEntity entity;
                    DrawUserDetailEntity detailEntity = userDetailMap.get(item.getUserId());// 用户可抽盲盒记录
                    int walletNum = 0, spotNum = 0, swapNum = 0;
                    if (detailEntity == null) {// 没有抽盲盒记录，直接计算该用户是否符合抽奖
                        entity = saveUserDetailMap.get(item.getUserId());
                        if (entity == null) {
                            entity = new DrawUserDetailEntity();
                            entity.setDrawId(drawEntity.getId());
                            entity.setUserId(item.getUserId());
                            saveUserDetailMap.put(item.getUserId(), entity);// 新增
                        }
                        if (drawEntity.getWalletLimit()
                                .compareTo(BigDecimal.ZERO) > 0) {
                            BigDecimal[] walletArr = wallet.divideAndRemainder(drawEntity.getWalletLimit());
                            walletNum = Integer.valueOf(walletArr[0].stripTrailingZeros()
                                                            .toPlainString());
                            if (walletNum > drawEntity.getWalletNumber()) {
                                walletNum = drawEntity.getWalletNumber();
                                item.setWalletLimit(BigDecimal.valueOf(walletNum)
                                                        .multiply(drawEntity.getWalletLimit()));
                            }
                        }
                        if (drawEntity.getSpotLimit()
                                .compareTo(BigDecimal.ZERO) > 0) {
                            BigDecimal[] spotArr = spot.divideAndRemainder(drawEntity.getSpotLimit());
                            spotNum = Integer.valueOf(spotArr[0].stripTrailingZeros()
                                                          .toPlainString());
                            if (spotNum > drawEntity.getSpotNumber()) {
                                spotNum = drawEntity.getSpotNumber();
                                item.setSpotLimit(BigDecimal.valueOf(spotNum)
                                                      .multiply(drawEntity.getSpotLimit()));
                            }
                        }
                        if (drawEntity.getSwapLimit()
                                .compareTo(BigDecimal.ZERO) > 0) {
                            BigDecimal[] swapArr = swap.divideAndRemainder(drawEntity.getSwapLimit());
                            swapNum = Integer.valueOf(swapArr[0].stripTrailingZeros()
                                                          .toPlainString());
                            if (swapNum > drawEntity.getSwapNumber()) {
                                swapNum = drawEntity.getSwapNumber();
                                item.setSwapLimit(BigDecimal.valueOf(swapNum)
                                                      .multiply(drawEntity.getSwapLimit()));
                            }
                        }
                    } else {
                        entity = upUserDetailMap.get(item.getUserId());
                        if (entity == null) {
                            entity = new DrawUserDetailEntity();
                            entity.setDrawId(drawEntity.getId());
                            entity.setUserId(item.getUserId());
                            upUserDetailMap.put(item.getUserId(), entity);// 修改
                        }
                        if (detailEntity.getInviterWallet() < drawEntity.getWalletNumber() && drawEntity.getWalletLimit()
                                                                                                  .compareTo(BigDecimal.ZERO) >
                                                                                              0) {
                            BigDecimal[] walletArr = wallet.subtract(BigDecimal.valueOf(detailEntity.getInviterWallet())
                                                                         .multiply(drawEntity.getWalletLimit()))
                                .divideAndRemainder(drawEntity.getWalletLimit());
                            walletNum = Integer.valueOf(walletArr[0].stripTrailingZeros()
                                                            .toPlainString());
                            if (walletNum > (drawEntity.getWalletNumber() - detailEntity.getInviterWallet())) {
                                walletNum = drawEntity.getWalletNumber() - detailEntity.getInviterWallet();
                                item.setWalletLimit(BigDecimal.valueOf(walletNum)
                                                        .multiply(drawEntity.getWalletLimit()));
                            }
                        } else {
                            item.setWalletLimit(BigDecimal.ZERO);
                        }
                        if (detailEntity.getInviterSpot() < drawEntity.getSpotNumber() && drawEntity.getSpotLimit()
                                                                                              .compareTo(BigDecimal.ZERO) > 0) {
                            BigDecimal[] spotArr = spot.subtract(BigDecimal.valueOf(detailEntity.getInviterSpot())
                                                                     .multiply(drawEntity.getSpotLimit()))
                                .divideAndRemainder(drawEntity.getSpotLimit());
                            spotNum = Integer.valueOf(spotArr[0].stripTrailingZeros()
                                                          .toPlainString());
                            if (spotNum > (drawEntity.getSpotNumber() - detailEntity.getInviterSpot())) {
                                spotNum = drawEntity.getSpotNumber() - detailEntity.getInviterSpot();
                                item.setSpotLimit(BigDecimal.valueOf(spotNum)
                                                      .multiply(drawEntity.getSpotLimit()));
                            }
                        } else {
                            item.setSpotLimit(BigDecimal.ZERO);
                        }
                        if (detailEntity.getInviterSwap() < drawEntity.getSwapNumber() && drawEntity.getSwapLimit()
                                                                                              .compareTo(BigDecimal.ZERO) > 0) {
                            BigDecimal[] swapArr = swap.subtract(BigDecimal.valueOf(detailEntity.getInviterSwap())
                                                                     .multiply(drawEntity.getSwapLimit()))
                                .divideAndRemainder(drawEntity.getSwapLimit());
                            swapNum = Integer.valueOf(swapArr[0].stripTrailingZeros()
                                                          .toPlainString());
                            if (swapNum > (drawEntity.getSwapNumber() - detailEntity.getInviterSwap())) {
                                swapNum = drawEntity.getSwapNumber() - detailEntity.getInviterSwap();
                                item.setSwapLimit(BigDecimal.valueOf(swapNum)
                                                      .multiply(drawEntity.getSwapLimit()));
                            }
                        } else {
                            item.setSwapLimit(BigDecimal.ZERO);
                        }
                    }
                    entity.setInviterWallet(walletNum);
                    entity.setInviterSpot(spotNum);
                    entity.setInviterSwap(swapNum);
                    int available = walletNum + spotNum + swapNum;// 总次数
                    entity.setAvailable(available);
                    if (available > 0) {// 当下级有抽奖次数时查看上级
                        Long inviteeId = invitationMap.get(item.getUserId());
                        if (inviteeId != null && inviteeId > 0) {
                            DrawUserDetailEntity inviteeEntity;
                            if (invitationUserMap.get(inviteeId) == null) {
                                inviteeEntity = saveUserDetailMap.get(inviteeId);
                                if (inviteeEntity == null) {
                                    inviteeEntity = new DrawUserDetailEntity();
                                    inviteeEntity.setDrawId(drawEntity.getId());
                                    inviteeEntity.setUserId(inviteeId);
                                    inviteeEntity.setInviteeWallet(walletNum);
                                    inviteeEntity.setInviteeSpot(spotNum);
                                    inviteeEntity.setInviteeSwap(swapNum);
                                    inviteeEntity.setAvailable(available);
                                    saveUserDetailMap.put(inviteeId, inviteeEntity);// 新增
                                } else {
                                    inviteeEntity.setInviteeWallet(inviteeEntity.getInviteeWallet() + walletNum);
                                    inviteeEntity.setInviteeSpot(inviteeEntity.getInviteeSpot() + spotNum);
                                    inviteeEntity.setInviteeSwap(inviteeEntity.getInviteeSwap() + swapNum);
                                    inviteeEntity.setAvailable(inviteeEntity.getAvailable() + available);
                                }
                            } else {
                                inviteeEntity = upUserDetailMap.get(inviteeId);
                                if (inviteeEntity == null) {
                                    inviteeEntity = new DrawUserDetailEntity();
                                    inviteeEntity.setDrawId(drawEntity.getId());
                                    inviteeEntity.setUserId(inviteeId);
                                    inviteeEntity.setInviteeWallet(walletNum);
                                    inviteeEntity.setInviteeSpot(spotNum);
                                    inviteeEntity.setInviteeSwap(swapNum);
                                    inviteeEntity.setAvailable(available);
                                    upUserDetailMap.put(inviteeId, inviteeEntity);// 新增
                                } else {
                                    inviteeEntity.setInviteeWallet(inviteeEntity.getInviteeWallet() + walletNum);
                                    inviteeEntity.setInviteeSpot(inviteeEntity.getInviteeSpot() + spotNum);
                                    inviteeEntity.setInviteeSwap(inviteeEntity.getInviteeSwap() + swapNum);
                                    inviteeEntity.setAvailable(inviteeEntity.getAvailable() + available);
                                }
                            }
                        }
                    }
                    if (item.getWalletLimit()
                            .compareTo(BigDecimal.ZERO) <= 0
                        && item.getSpotLimit()
                               .compareTo(BigDecimal.ZERO) <= 0
                        && item.getSwapLimit()
                               .compareTo(BigDecimal.ZERO) <= 0) {
                        saveUserTotalMap.remove(item.getUserId());
                        upUserTotalMap.remove(item.getUserId());
                    }
                }

                resourceApi.upUserDetail(new DrawUpUserDetailRequest(new ArrayList<>(saveUserDetailMap.values()),
                                                                     new ArrayList<>(upUserDetailMap.values()),
                                                                     new ArrayList<>(saveUserTotalMap.values()),
                                                                     new ArrayList<>(upUserTotalMap.values())));


            }
        }

    }


    private BigDecimal newPirce(Map<String, BigDecimal> mapPrice,List<String> list,String currency){
        BigDecimal newPrice = BigDecimal.ZERO;
        if(currency.equals("usdt")){
            return BigDecimal.ONE;
        }
        if (mapPrice.get(currency) == null) {
            Object object = RedisUtil.hGet(ActivitySpoKeyConstants.Spot.NEW_PRICE, currency + "_usdt");
            if (object != null) {
                newPrice = JSON.parseObject(object.toString(), NewPriceEntity.class).getPrice();
            }else{
                for(String item : list){
                    object = RedisUtil.hGet(ActivitySpoKeyConstants.Spot.NEW_PRICE, currency + "_" + item);
                    if(object != null){
                        newPrice = JSON.parseObject(object.toString(), NewPriceEntity.class).getPrice();
                        Object itemObject = RedisUtil.hGet(ActivitySpoKeyConstants.Spot.NEW_PRICE, item + "_usdt");
                        BigDecimal itemNewPrice = JSON.parseObject(itemObject.toString(), NewPriceEntity.class).getPrice();
                        newPrice = newPrice.multiply(itemNewPrice).setScale(12,BigDecimal.ROUND_DOWN);
                    }
                }
            }
            mapPrice.put(currency, newPrice);
        } else {
            newPrice = mapPrice.get(currency);
        }
        return newPrice;
    }
}
